package com.bc.trade.channel.gzdcdata;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bc.common.CommonEnum.OrderStatus;
import com.bc.common.CommonEnum.Resp;
import com.bc.common.ThreadShare;
import com.bc.common.message.DFReq;
import com.bc.common.message.DFResp;
import com.bc.trade.channel.IChannel;
import com.bc.trade.message.BindBankCardReq;
import com.bc.trade.message.BindBankCardResp;
import com.bc.trade.message.BindBankCardVerifyReq;
import com.bc.trade.message.BindBankCardVerifyResp;
import com.bc.trade.message.QueryCardInfoReq;
import com.bc.trade.message.QueryCardInfoResp;
import com.bc.trade.message.QueryOrderResp;
import com.bc.trade.message.QuickPayReq;
import com.bc.trade.message.QuickPayResp;
import com.bc.trade.message.QuickPaySetReq;
import com.bc.trade.message.QuickPaySetResp;
import com.bc.trade.message.RefundReq;
import com.bc.trade.message.RefundResp;
import com.bc.trade.message.SendSMSReq;
import com.bc.trade.message.SendSMSResp;
import com.bc.trade.message.UnionPayReq;
import com.bc.trade.message.UnionPayResp;
import com.bc.trade.model.TradeOrder;
import com.fs.common.util.FSHttp;
import com.fs.common.util.FSIDGenerate;

public class GzdcdataChannel implements IChannel {

	private final String notifyUrl = "http://pay.lihaishop.com:8080/notify/merchReturn";

	String userId = "500000500";
	String signKey = "ffffffffffffffffffffffffffffffff";
	String dataKey = "ffffffffffffffffffffffffffffffff";
	String url = "http://pos.gzdcdata.com/dcpay";

	@Override
	public QueryOrderResp query(TradeOrder order) throws Exception {
		QueryOrderResp rsp = new QueryOrderResp();
		Map<String, String> postParamMap = new HashMap<String, String>();
		postParamMap.put("type", "QpayBindOrder");// 固定数据
		postParamMap.put("characterSet", "02");// 目前只支持 02- UTF-8
		postParamMap.put("ipAddress", ThreadShare.ClientIP.get());// 用户浏览器的IP地址
		postParamMap.put("version", "1.0.0");// 版本号
		postParamMap.put("signType", "01");// 签名方式MD5

		// payNo、requestId传其中的一个，都传只用流水号(payNo)
		// postParamMap.put("payNo", "10000390");// 0 T0、1 T1
		postParamMap.put("requestId", order.getOrderNo());// 用户请求的交易流水号唯一
		postParamMap.put("userId", userId);// 用户id

		String hmac = MerchSdkSign.getSign(postParamMap, signKey);
		postParamMap.put("hmac", hmac);//
		String reqJson = JSON.toJSONString(postParamMap);
		System.out.println("请求万钻电子发送报文：-->[" + reqJson + "]");
		String rspJson = FSHttp.postJson(url, reqJson);
		System.out.println("接收万钻电子响应报文：<--[" + rspJson + "]");

		JSONObject map = JSON.parseObject(rspJson);
		if ("000000".equals(map.getString("returnCode"))) {
			// 验签
			hmac = map.getString("hmac");
			map.remove("hmac");// 返回数据签名不包含签名数据
			if (Objects.equals(hmac, MerchSdkSign.getSign(map, signKey))) {
				if ("S".equals(map.getString("ordersts"))) {
					rsp.setOriginalRespCode(Resp.Success.getCode());
					rsp.setOriginalRespMsg(Resp.Success.getMsg());
				} else if ("F".equals(map.getString("ordersts"))) {
					rsp.setOriginalRespCode(Resp.Fail.getCode());
					rsp.setOriginalRespMsg(Resp.Fail.getMsg());
				} else {
					rsp.setOriginalRespCode(Resp.InProcess.getCode());
					rsp.setOriginalRespMsg(Resp.InProcess.getMsg());
				}
				rsp.setCodeAndMsg(Resp.Success.getCode(), Resp.Success.getMsg());
			} else {
				rsp.setCodeAndMsg(Resp.Fail.getCode(), "通道验证失败");
			}
		} else {
			rsp.setOriginalRespCode(Resp.InProcess.getCode());
			rsp.setOriginalRespMsg(Resp.InProcess.getMsg());
			rsp.setCodeAndMsg(Resp.Fail.getCode(),
					"失败CH(" + map.getString("returnCode") + "-" + map.getString("message") + ")");
		}
		return rsp;
	}

	@Override
	public QueryOrderResp dfQuery(TradeOrder order) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public DFResp df(DFReq req, TradeOrder order) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public UnionPayResp unionpay(UnionPayReq req, TradeOrder order) throws Exception {
		UnionPayResp rsp = new UnionPayResp(req);
		Map<String, String> postParamMap = new HashMap<String, String>();
		postParamMap.put("type", "WangGuan"); // 固定数据
		postParamMap.put("characterSet", "02"); // 目前只支持 02- UTF-8
		postParamMap.put("ipAddress", ThreadShare.ClientIP.get()); // 用户浏览器的IP地址
		postParamMap.put("version", "1.0.0"); // 版本号
		postParamMap.put("signType", "01"); // 签名方式MD5
		postParamMap.put("tranCode", "B2B"); // 按需要可填B2C或WAP
		postParamMap.put("accountType", "0"); // 0 T0、1 T1
		postParamMap.put("requestId", order.getOrderNo());// 用户请求的交易流水号唯一
		postParamMap.put("userId", userId); // 用户id
		// postParamMap.put("amount", Integer.toString(order.getAmount()));//单位 分
		postParamMap.put("amount", Integer.toString(order.getAmount()));// 单位 分
		postParamMap.put("orderTitle", order.getGoodsName()); // 产品
		postParamMap.put("callBackUrl", notifyUrl);
		postParamMap.put("backUrl", order.getReturnUrl());

		String hmac = MerchSdkSign.getSign(postParamMap, signKey);
		postParamMap.put("hmac", hmac);

		String reqJson = JSON.toJSONString(postParamMap);
		System.out.println("请求万钻电子发送报文：-->[" + reqJson + "]");
		String rspJson = FSHttp.postJson(url, reqJson);
		System.out.println("接收万钻电子响应报文：<--[" + rspJson + "]");

		JSONObject map = JSON.parseObject(rspJson);
		if ("000000".equals(map.getString("returnCode"))) {
			// 下单成功
			order.setRespCode(Resp.InProcess.getCode());
			order.setRespMsg(Resp.InProcess.getMsg());
			// 验签
			hmac = map.getString("hmac");
			map.remove("hmac");// 返回数据签名不包含签名数据
			if (Objects.equals(hmac, MerchSdkSign.getSign(map, signKey))) {
				rsp.setType("1");
				rsp.setUrl(map.getString("qrCodeUrl"));
				rsp.setCodeAndMsg(Resp.Success.getCode(), Resp.Success.getMsg());
			} else {
				rsp.setCodeAndMsg(Resp.Fail.getCode(), "通道验证失败");
			}
		} else {
			order.setRespCode(Resp.Fail.getCode());
			order.setRespMsg(map.getString("message"));
			order.setOrderStatus(OrderStatus.Fail.getValue());
			rsp.setCodeAndMsg(Resp.Fail.getCode(), "失败CH(" + map.getString("returnCode") + "-" + map.getString("message") + ")");
		}
		return rsp;
	}

	@Override
	public QuickPaySetResp quickPaySet(QuickPaySetReq req, TradeOrder order) throws Exception {
		QuickPaySetResp rsp = new QuickPaySetResp(req);
		// 快捷绑卡预下单
		Map<String,String> accessDkRequest = new LinkedHashMap<String,String>();
		accessDkRequest.put("characterSet", "02");
		accessDkRequest.put("ipAddress", ThreadShare.ClientIP.get());
		accessDkRequest.put("signType", "01");
		accessDkRequest.put("version", "1.0.0");
		accessDkRequest.put("userId", userId);
		accessDkRequest.put("type","QpayBindOrder");
		accessDkRequest.put("accountType","0");// 结算周期：传0
		accessDkRequest.put("requestId",order.getOrderNo());
		accessDkRequest.put("amount",Integer.toString(order.getAmount()));	//交易金额，单位：分
		accessDkRequest.put("protocolNo",req.getVerifyId()); //协议号
		accessDkRequest.put("userToken",ThreeDesUtil.encryptPadFF(dataKey, req.getPhone()));
		accessDkRequest.put("bankCardNo",ThreeDesUtil.encryptPadFF(dataKey, req.getCardNo()));
		accessDkRequest.put("callBackUrl", notifyUrl);

		String hmac = MerchSdkSign.getSign(accessDkRequest, signKey);
		accessDkRequest.put("hmac", hmac);
		String reqJson = JSON.toJSONString(accessDkRequest);
		System.out.println("请求万钻电子发送报文：-->[" + reqJson + "]");
		String rspJson = FSHttp.postJson(url, reqJson);
		System.out.println("接收万钻电子响应报文：<--[" + rspJson + "]");

		JSONObject map = JSON.parseObject(rspJson);
		if ("000000".equals(map.getString("returnCode"))) {
			// 下单成功
			order.setRespCode(Resp.InProcess.getCode());
			order.setRespMsg(Resp.InProcess.getMsg());
			order.setOrderStatus(OrderStatus.InProcess.getValue());
			// 验签
			hmac = map.getString("hmac");
			map.remove("hmac");// 返回数据签名不包含签名数据
			if (Objects.equals(hmac, MerchSdkSign.getSign(map, signKey))) {
				order.setChannelOrderNo(map.getString("payNo"));
				rsp.setToken(map.getString("payNo"));
				rsp.setCodeAndMsg(Resp.Success.getCode(), map.getString("message"));
			} else {
				rsp.setCodeAndMsg(Resp.Fail.getCode(), "通道验证失败");
			}
		} else {
			order.setRespCode(Resp.Fail.getCode());
			order.setRespMsg(map.getString("message"));
			order.setOrderStatus(OrderStatus.Fail.getValue());
			rsp.setCodeAndMsg(Resp.Fail.getCode(), "失败CH(" + map.getString("returnCode") + "-" + map.getString("message") + ")");
		}
		return rsp;
	}

	@Override
	public QuickPayResp quickPay(QuickPayReq req, TradeOrder order) throws Exception {
		QuickPayResp rsp = new QuickPayResp(req);
		Map<String, String> accessDkRequest = new LinkedHashMap<String, String>();
		accessDkRequest.put("characterSet", "02");
		accessDkRequest.put("ipAddress", ThreadShare.ClientIP.get());
		accessDkRequest.put("signType", "01");
		accessDkRequest.put("version", "1.0.0");
		accessDkRequest.put("userId", userId);
		accessDkRequest.put("type", "QpayBindPay");
		accessDkRequest.put("requestId", order.getOrderNo());
		accessDkRequest.put("authCode", req.getSmsCode());
		accessDkRequest.put("payNo", req.getToken());// 预下单返回

		String hmac = MerchSdkSign.getSign(accessDkRequest, signKey);
		accessDkRequest.put("hmac", hmac);
		String reqJson = JSON.toJSONString(accessDkRequest);
		System.out.println("请求万钻电子发送报文：-->[" + reqJson + "]");
		String rspJson = FSHttp.postJson(url, reqJson);
		System.out.println("接收万钻电子响应报文：<--[" + rspJson + "]");

		JSONObject map = JSON.parseObject(rspJson);
		if ("000000".equals(map.getString("returnCode"))) {
			// 验签
			hmac = map.getString("hmac");
			map.remove("hmac");// 返回数据签名不包含签名数据
			if (Objects.equals(hmac, MerchSdkSign.getSign(map, signKey))) {
				// 交易成功
				order.setRespCode(Resp.Success.getCode());
				order.setRespMsg(Resp.Success.getMsg());
				order.setOrderStatus(OrderStatus.Success.getValue());
				rsp.setCodeAndMsg(Resp.Success.getCode(), Resp.Success.getMsg());
			} else {
				rsp.setCodeAndMsg(Resp.Fail.getCode(), "通道验证失败");
			}
		} else {
			order.setRespCode(Resp.Fail.getCode());
			order.setRespMsg(map.getString("message"));
			order.setOrderStatus(OrderStatus.Fail.getValue());
			rsp.setCodeAndMsg(Resp.Fail.getCode(), "失败CH(" + map.getString("returnCode") + "-" + map.getString("message") + ")");
		}
		return rsp;
	}

	@Override
	public SendSMSResp sendSMS(SendSMSReq req) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public QueryCardInfoResp queryCardInfo(QueryCardInfoReq req) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public RefundResp refund(RefundReq req, TradeOrder refundOrder, TradeOrder orignOrder) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	// 快捷绑卡申请
	@Override
	public BindBankCardResp bindBankCard(BindBankCardReq req, TradeOrder order) throws Exception {
		BindBankCardResp rsp = new BindBankCardResp(req);
		Map<String, String> accessDkRequest = new LinkedHashMap<String, String>();
		accessDkRequest.put("characterSet", "02");
		accessDkRequest.put("ipAddress", ThreadShare.ClientIP.get());
		accessDkRequest.put("signType", "01");
		accessDkRequest.put("version", "1.0.0");
		accessDkRequest.put("userId", userId);
		accessDkRequest.put("type", "QpayBindApply");
		accessDkRequest.put("requestId", order.getOrderNo());
		accessDkRequest.put("certNo", ThreeDesUtil.encryptIDCard(dataKey, req.getCertNo()));
		accessDkRequest.put("userToken", ThreeDesUtil.encryptPadFF(dataKey, req.getPhone()));
		accessDkRequest.put("payerName", req.getName());
		accessDkRequest.put("bankCardNo", ThreeDesUtil.encryptPadFF(dataKey, req.getCardNo()));
		accessDkRequest.put("bankCardTyp", req.getCardType());// 银行卡类型 :0为借记卡，1为贷记卡，枚举值与我方系统一致
		// 贷记卡必填
		if("1".equals(req.getCardType())) {
			accessDkRequest.put("lastThreeNo", req.getCvn2());
			accessDkRequest.put("cardExpMonth", req.getExpired().substring(0, 2));
			accessDkRequest.put("cardExpYear", req.getExpired().substring(2, 4));
		}
		String hmac = MerchSdkSign.getSign(accessDkRequest, signKey);
		accessDkRequest.put("hmac", hmac);
		String reqJson = JSON.toJSONString(accessDkRequest);
		System.out.println("请求万钻电子发送报文：-->[" + reqJson + "]");
		String rspJson = FSHttp.postJson(url, reqJson);
		System.out.println("接收万钻电子响应报文：<--[" + rspJson + "]");

		JSONObject map = JSON.parseObject(rspJson);
		if ("000000".equals(map.getString("returnCode"))) {
			// 验签
			hmac = map.getString("hmac");
			map.remove("hmac");// 返回数据签名不包含签名数据
			if (Objects.equals(hmac, MerchSdkSign.getSign(map, signKey))) {
				// 申请成功
				order.setChannelOrderNo(map.getString("quickTransId"));
				rsp.setCodeAndMsg(Resp.Success.getCode(), map.getString("message"));
			} else {
				rsp.setCodeAndMsg(Resp.Fail.getCode(), "通道验证失败");
			}
		} else {
			rsp.setCodeAndMsg(Resp.Fail.getCode(), "绑卡失败CH(" + map.getString("returnCode") + "-" + map.getString("message") + ")");
		}
		return rsp;
	}

	// 快捷确认绑卡并获取协议号数据
	@Override
	public BindBankCardVerifyResp bindBankCardVerify(BindBankCardVerifyReq req, TradeOrder order) throws Exception {
		BindBankCardVerifyResp rsp = new BindBankCardVerifyResp(req);
		Map<String, String> accessDkRequest = new LinkedHashMap<String, String>();
		accessDkRequest.put("characterSet", "02");
		accessDkRequest.put("ipAddress", ThreadShare.ClientIP.get());
		accessDkRequest.put("signType", "01");
		accessDkRequest.put("version", "1.0.0");
		accessDkRequest.put("userId", userId);
		accessDkRequest.put("type", "QpayBindConfirm");
		accessDkRequest.put("requestId", FSIDGenerate.nextOrderNo());
		accessDkRequest.put("bankCardNo", ThreeDesUtil.encryptPadFF(dataKey, req.getCardNo()));
		accessDkRequest.put("userToken", ThreeDesUtil.encryptPadFF(dataKey, req.getPhone()));
		accessDkRequest.put("quickTransId", order.getChannelOrderNo()); // 绑卡返回码
		accessDkRequest.put("authCode", req.getSmsCode()); // 短信验证码

		String hmac = MerchSdkSign.getSign(accessDkRequest, signKey);
		accessDkRequest.put("hmac", hmac);
		String reqJson = JSON.toJSONString(accessDkRequest);
		System.out.println("请求万钻电子发送报文：-->[" + reqJson + "]");
		String rspJson = FSHttp.postJson(url, reqJson);
		System.out.println("接收万钻电子响应报文：<--[" + rspJson + "]");

		JSONObject map = JSON.parseObject(rspJson);
		if ("000000".equals(map.getString("returnCode"))) {
			// 验签
			hmac = map.getString("hmac");
			map.remove("hmac");// 返回数据签名不包含签名数据
			if (Objects.equals(hmac, MerchSdkSign.getSign(map, signKey))) {
				// 申请成功
				rsp.setVerifyId(map.getString("protocolNo"));
				order.setRemark(rsp.getVerifyId());// 记录协议号
				rsp.setCodeAndMsg(Resp.Success.getCode(), map.getString("returnCode"));
			} else {
				rsp.setCodeAndMsg(Resp.Fail.getCode(), "通道验证失败");
			}
		} else {
			rsp.setCodeAndMsg(Resp.Fail.getCode(), "绑卡失败CH(" + map.getString("returnCode") + "-" + map.getString("message") + ")");
		}
		return rsp;
	}
}
